include(core.m4)
include(assert.m4)
include(classes.m4)

dnl Если первый параметр не пуст, подставляет второй, иначе третий параметр
define({IFFIRST},{ifelse($1,{},$3,$2)})

dnl Конструкция RETURN
dnl Можно использовать без параметров, подставится Exit
dnl С параметром подставится begin Result := параметр; Exit; end;
define({RETURN},{begin IFFIRST($1,Result := $1;) Exit; end})

define({PROTOTYPE},{define($1,$2)}) dnl PROTOTYPE(SomeFunc, function OnClick(Button: Integer): Boolean;)

define({INIT},{begin ifelse($1,{},with $2,$1 := $2; with $1) do begin $3 end; end})

define({FOR},{for $1 := 0 to $2 - 1 do begin $3 end})
define({ARRFOR},{FOR($1,High($2),$3)})

dnl objects
define({OBJECT},{dnl(
    define({OBJECT_NAME},$1)
    define({TOBJECT_NAME},T$1)
    define({POBJECT_NAME},P$1)
    SETNULL(OBJECT_IMPLEMENTATION)
    SETNULL(OBJECT_PRIVATE)
    SETNULL(OBJECT_PROTECTED)
    SETNULL(OBJECT_PUBLIC))
T$1 = object$2 dnl
})
define({_OBJECT},{dnl
  private OBJECT_PRIVATE
  protected OBJECT_PROTECTED
  public OBJECT_PUBLIC
end;
})
define({POBJECT}, {P$1 = ^T$1; OBJECT($1,$2,$3)})
define({FMETHOD}, {dnl
    define({METHOD_NAME}, $1) dnl
  function $1$2: $3; $4 dnl 
    SETNULL(METHOD_LOCALVARS) dnl
    define({METHOD_BODY}, $5) dnl
    APPEND({OBJECT_IMPLEMENTATION}, 
           { function TOBJECT_NAME.$1$2: $3;dnl 
             IFFIRST(METHOD_LOCALVARS,var METHOD_LOCALVARS) dnl
             begin dnl
               METHOD_BODY dnl
             end;})})
define({PMETHOD}, {procedure $1$2; $3})
define({PRIVATE}, {APPEND({OBJECT_PRIVATE}, F$1: $2;)})
define({PROTECTED}, {APPEND({OBJECT_PROTECTED}, F$1: $2;) dnl
                     APPEND({OBJECT_PUBLIC}, property $1: $2 read F$1;)})

dnl Объявляем глобальные переменные
SETNULL({OBJECT_IMPLEMENTATION})
SETNULL(OBJECT_PRIVATE) dnl
SETNULL(OBJECT_PROTECTED) dnl
SETNULL(OBJECT_PUBLIC) dnl
)
divert
